package com.farmer.redpacket.controller;

import com.farmer.redpacket.entity.RedPacket;
import com.farmer.redpacket.exceptions.ExceptionType;
import com.farmer.redpacket.exceptions.ServiceException;
import com.farmer.redpacket.inout.CommonJsonRequest;
import com.farmer.redpacket.inout.CommonJsonResponse;
import com.farmer.redpacket.inout.in.ReqOrderPayCallbackVO;
import com.farmer.redpacket.inout.in.ReqReceiveListVO;
import com.farmer.redpacket.inout.in.ReqReceiveRedPacketVO;
import com.farmer.redpacket.inout.in.ReqSendRedPacketsVO;
import com.farmer.redpacket.inout.out.RespOrderPayCallbackVO;
import com.farmer.redpacket.inout.out.RespReceiveListVO;
import com.farmer.redpacket.inout.out.RespSendRedPacketsVO;
import com.farmer.redpacket.service.RedPacketOrderService;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpSession;
import java.math.BigDecimal;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author tech-farmer
 * @ClassName: RedPacketsController
 * @Description: (这里用一句话描述这个类的作用)
 * @date 2021/11/16 15:04
 */
@RestController
@RequestMapping("/redpackets")
public class RedPacketsController {

    private final RedPacketOrderService orderService;

    public RedPacketsController(RedPacketOrderService orderService) {
        this.orderService = orderService;
    }

    @PostMapping("/send")
    public CommonJsonResponse<RespSendRedPacketsVO> sendRedPackets(@Validated @RequestBody CommonJsonRequest<ReqSendRedPacketsVO> vo,HttpSession session) {
        final ReqSendRedPacketsVO data = vo.getData();
        //最小红包金额
        final BigDecimal min = new BigDecimal("0.01");
        //发红包金额
        final BigDecimal amount = data.getAmount();
        //红包数量
        final Integer num = data.getNum();
        //每个红包0.01元最少需要金额
        final BigDecimal atLastAmount = min.multiply(new BigDecimal(num));
        if (amount.compareTo(atLastAmount) < 0) {
            throw new ServiceException("红包金额与红包数量不匹配", ExceptionType.ILLEGAL_PARAM);
        }
        final RedPacket redPacketOrder = orderService.generateRedPacket(data,session.getId());
        return CommonJsonResponse.ok(RespSendRedPacketsVO.builder()
                .packetId(redPacketOrder.getId())
                .packetNo(redPacketOrder.getPacketNo())
                .paySeq(redPacketOrder.getPaySeq())
                .build());
    }

    @PostMapping("/payCallback")
    public CommonJsonResponse<RespOrderPayCallbackVO> payCallback(@Validated @RequestBody CommonJsonRequest<ReqOrderPayCallbackVO> vo, HttpSession session) {
        final Integer payStatus = vo.getData().getPayStatus();
        if (payStatus != 2 && payStatus != 3) {
            throw new ServiceException("支付状态无法处理", ExceptionType.ILLEGAL_PARAM);
        }
        orderService.dealAfterOrderPayCallback(session.getId(),vo.getData());
        return CommonJsonResponse.ok();
    }

    private AtomicInteger receiveCount = new AtomicInteger(0);

    @PostMapping("/receive")
    public CommonJsonResponse receiveOne(@Validated @RequestBody CommonJsonRequest<ReqReceiveRedPacketVO> vo) {
        Integer num = null;
        try {
            //控制并发不要超过20
            if (receiveCount.get() > 20) {
                return new CommonJsonResponse("9999", "太快了");
            }
            num = receiveCount.incrementAndGet();
            final String s = orderService.receiveOne(vo.getData());
            return StringUtils.isEmpty(s) ? CommonJsonResponse.ok() : new CommonJsonResponse("9999", s);
        } finally {
            if (num != null) {
                receiveCount.decrementAndGet();
            }
        }
    }


    private AtomicInteger openCount = new AtomicInteger(0);

    @PostMapping("/open")
    public CommonJsonResponse open(@Validated @RequestBody CommonJsonRequest<ReqReceiveRedPacketVO> vo) {
        Integer num = null;
        try {
            //控制并发不要超过20
            if (openCount.get() > 20) {
                return new CommonJsonResponse("9999", "太快了");
            }
            num = openCount.incrementAndGet();
            return new CommonJsonResponse("0000", orderService.openRedPacket(vo.getData()));
        } finally {
            if (num != null) {
                openCount.decrementAndGet();
            }
        }
    }


    @PostMapping("/receiveList")
    public CommonJsonResponse<RespReceiveListVO> receiveList(@Validated @RequestBody CommonJsonRequest<ReqReceiveListVO> vo) {
        Integer num = null;
        try {
            //控制并发不要超过20
            if (openCount.get() > 20) {
                return new CommonJsonResponse("9999", "太快了");
            }
            num = openCount.incrementAndGet();
            return CommonJsonResponse.ok(orderService.receiveList(vo.getData()));
        } finally {
            if (num != null) {
                openCount.decrementAndGet();
            }
        }
    }


}
